﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.ServiceLocation;
using Pap.Core.Utilities;
using Pap.Data;
using Pap.Data.Abstraction.Utils;
using Pap.Services;
using Pap.Services.WorkflowEngine;
using Pap.Web.Utils;
using Utils;

namespace Pap.Web.Modules.Loan.ViewModel
{
    /// <summary>
    /// 
    /// </summary>
    public class PaymentOldDateControlViewModel : IViewModel
    {
        /// <summary>
        /// 
        /// </summary>
        IWorkflowService _WorkFlowService;
        /// <summary>
        /// 
        /// </summary>
        ILoanRepository _LoanRepository;
        /// <summary>
        /// 
        /// </summary>
        IAdministrationRepository _AdministrationRepository;

        /// <summary>
        /// Initializes a new instance of the <see cref="PaymentOldDateControlViewModel"/> class.
        /// </summary>
        /// <param name="workFlowService">The work flow service.</param>
        /// <param name="loanRepository">The loan repository.</param>
        /// <param name="AdminRepository">The admin repository.</param>
        public PaymentOldDateControlViewModel(IWorkflowService workFlowService, ILoanRepository loanRepository, IAdministrationRepository AdminRepository)
        {
            _WorkFlowService = workFlowService;
            _LoanRepository = loanRepository;
            _AdministrationRepository = AdminRepository;
        }

        /// <summary>
        /// Gets the old date payment loans.
        /// </summary>
        /// <returns></returns>
        public IEnumerable GetOldDatePaymentLoans()
        {
            var loanIDs = _WorkFlowService.GetInStep(Steps.ReviewerPaymentOldDateApprove);
            IEnumerable<IProject> userProjects = _AdministrationRepository.GetUserProjects(RegistryInfo.UserID);
            var oldPaymentLoans = _LoanRepository.FindCustomerLoans(loan => loanIDs.Contains(loan.LoanID) );
            oldPaymentLoans = oldPaymentLoans.Where(loan => userProjects.Contains(loan.ProjectStage.ProjectObj));
            return (from loan in oldPaymentLoans
                    let step = _WorkFlowService.GetStep(_WorkFlowService.GetProcessInstanceIDByEntity(loan.LoanID))
                    select new
                    {
                        LoanID = loan.LoanID,
                        LoanNumber = loan.LoanNumber,
                        CustomerName = loan.CustomerObj.CustomerName,
                        OldPaymentDate = step.CompletionDate
                    });
        }

        /// <summary>
        /// Gets the available decisions.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<ActionTypes> GetAvailableDecisions()
        {
            return _WorkFlowService.GetAvailableActionsByStep(Steps.ReviewerPaymentOldDateApprove);
        }

        /// <summary>
        /// Takes the loan decisions.
        /// </summary>
        /// <param name="loansIDs">The loans I ds.</param>
        /// <param name="loanDecisions">The loan decisions.</param>
        /// <param name="notes">The notes.</param>
        public void TakeLoanDecisions(List<Guid> loansIDs, List<ActionTypes> loanDecisions, List<string> notes)
        {
            using (IUnitOfWork trancaction = ServiceLocator.Current.GetInstance<IUnitOfWork>())
            {
                for (int i = 0; i < loanDecisions.Count; i++)
                {
                    Guid processInstanceID = _WorkFlowService.GetProcessInstanceIDByEntity(loansIDs[i]);
                    var step = _WorkFlowService.GetStep(processInstanceID);
                    if ((Enums.ToString(loanDecisions[i]).ToGuid()).Equals(Enums.ToString(ActionTypes.Accept).ToGuid()))
                        _WorkFlowService.Move(loanDecisions[i], processInstanceID, RegistryInfo.UserID, notes[i], step.CompletionDate);
                    else
                        _WorkFlowService.Move(loanDecisions[i], processInstanceID, RegistryInfo.UserID, notes[i], null);
                }

                trancaction.Commit();
            }
        }
    }
}
